home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / libs / sphigs / sph_mac.hqx / SRGP port to 5.0 (compressed) / SRGP_SPHIGS Root / MacSPHIGS / MAT3geom.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-02-13  |  4.7 KB  |  169 lines

  1. #include "HEADERS.h"
  2. /* Copyright 1988, Brown Computer Graphics Group.  All Rights Reserved. */
  3.  
  4. /* --------------------------------------------------------------------------
  5.  * This file contains routines that perform geometry-related operations
  6.  * on matrices.
  7.  * -------------------------------------------------------------------------*/
  8.  
  9. #include "mat3defs.h"
  10.  
  11. #include "MAT3geom.proto.h"
  12.  
  13. /* --------------------------  Static Routines    ---------------------------- */
  14.  
  15. /* -------------------------  Internal Routines  --------------------------- */
  16.  
  17. /* --------------------------  Public Routines    ---------------------------- */
  18.  
  19. /*
  20.  * This takes a matrix used to transform points, and returns a corresponding
  21.  * matrix that can be used to transform direction vectors (between points).
  22.  */
  23.  
  24. void
  25. MAT3direction_matrix(MAT3mat result_mat, MAT3mat mat)
  26. {
  27.    register int i;
  28.  
  29.    MAT3copy(result_mat, mat);
  30.  
  31.    for (i = 0; i < 4; i++) result_mat[i][3] = result_mat[3][i] = 0.0;
  32.  
  33.    result_mat[3][3] = 1.0;
  34. }
  35.  
  36. /*
  37.  * This takes a matrix used to transform points, and returns a corresponding
  38.  * matrix that can be used to transform vectors that must remain perpendicular
  39.  * to planes defined by the points.  It is useful when you are transforming
  40.  * some object that has both points and normals in its definition, and you
  41.  * only have the transformation matrix for the points.    This routine returns
  42.  * FALSE if the normal matrix is uncomputable.    Otherwise, it returns TRUE.
  43.  *
  44.  * Spike sez: "This is the adjoint for the non-homogeneous part of the
  45.  *           transformation."
  46.  */
  47.  
  48. int
  49. MAT3normal_matrix(MAT3mat result_mat, MAT3mat mat)
  50. {
  51.    register int ret;
  52.    MAT3mat    tmp_mat;
  53.  
  54.    MAT3direction_matrix(result_mat, mat);
  55.  
  56.    if (ret = MAT3invert(tmp_mat, tmp_mat)) MAT3transpose(result_mat, tmp_mat);
  57.  
  58.    return(ret);
  59. }
  60.  
  61. /*
  62.  * Sets the given matrix to be a scale matrix for the given vector of
  63.  * scale values.
  64.  */
  65.  
  66. void
  67. MAT3scale(MAT3mat result_mat, MAT3vec scale)
  68. {
  69.    MAT3identity(result_mat);
  70.  
  71.    result_mat[0][0] = scale[0];
  72.    result_mat[1][1] = scale[1];
  73.    result_mat[2][2] = scale[2];
  74. }
  75.  
  76. /*
  77.  * Sets up a matrix for a rotation about an axis given by the line from
  78.  * (0,0,0) to axis, through an angle (in radians).
  79.  * Looking along the axis toward the origin, the rotation is counter-clockwise.
  80.  */
  81.  
  82. #define SELECT    .7071    /* selection constant (roughly .5*sqrt(2) */
  83.  
  84. void
  85. MAT3rotate(MAT3mat result_mat, MAT3vec axis, double angle_in_radians)
  86. {
  87.    MAT3vec    naxis,    /* Axis of rotation, normalized         */
  88.         base2,    /* 2nd unit basis vec, perp to axis        */
  89.         base3;    /* 3rd unit basis vec, perp to axis & base2    */
  90.    double    dot;
  91.    MAT3mat    base_mat,    /* Change-of-basis matrix        */
  92.         base_mat_trans; /* Inverse of c-o-b matrix        */
  93.    register int i;
  94.  
  95.    /* Step 1: extend { axis } to a basis for 3-space: { axis, base2, base3 }
  96.     * which is orthonormal (all three have unit length, and all three are
  97.     * mutually orthogonal). Also should be oriented, i.e. axis cross base2 =
  98.     * base3, rather than -base3.
  99.     *
  100.     * Method: Find a vector linearly independent from axis. For this we
  101.     * either use the y-axis, or, if that is too close to axis, the
  102.     * z-axis. 'Too close' means that the dot product is too near to 1.
  103.     */
  104.  
  105.    MAT3_COPY_VEC(naxis, axis);
  106.    MAT3_NORMALIZE_VEC(naxis, dot);
  107.  
  108.    if (dot == 0.0) {
  109.       ERR_ERROR(MAT3_errid, ERR_SEVERE,
  110.            (ERR_S, "Zero-length axis vector given to MAT3rotate"));
  111.       return;
  112.    }
  113.  
  114.    MAT3perp_vec(base2, naxis, TRUE);
  115.    MAT3cross_product(base3, naxis, base2);
  116.  
  117.    /* Set up the change-of-basis matrix, and its inverse */
  118.    MAT3identity(base_mat);
  119.    MAT3identity(base_mat_trans);
  120.    MAT3identity(result_mat);
  121.  
  122.    for (i = 0; i < 3; i++){
  123.       base_mat_trans[i][0] = base_mat[0][i] = naxis[i];
  124.       base_mat_trans[i][1] = base_mat[1][i] = base2[i];
  125.       base_mat_trans[i][2] = base_mat[2][i] = base3[i];
  126.    }
  127.  
  128.    /* If T(u) = uR, where R is base_mat, then T(x-axis) = naxis,
  129.     * T(y-axis) = base2, and T(z-axis) = base3. The inverse of base_mat is
  130.     * its transpose.  OK?
  131.     */
  132.  
  133.    result_mat[1][1] =    result_mat[2][2] = cos(angle_in_radians);
  134.    result_mat[2][1] = -(result_mat[1][2] = sin(angle_in_radians));
  135.  
  136.    MAT3mult(result_mat, base_mat_trans, result_mat);
  137.    MAT3mult(result_mat, result_mat,    base_mat);
  138. }
  139.  
  140. /*
  141.  * Sets the given matrix to be a translation matrix for the given vector of
  142.  * translation values.
  143.  */
  144.  
  145. void
  146. MAT3translate(MAT3mat result_mat, MAT3vec trans)
  147. {
  148.    MAT3identity(result_mat);
  149.  
  150.    result_mat[3][0] = trans[0];
  151.    result_mat[3][1] = trans[1];
  152.    result_mat[3][2] = trans[2];
  153. }
  154.  
  155. /*
  156.  * Sets the given matrix to be a shear matrix for the given x and y shear
  157.  * values.
  158.  */
  159.  
  160. void
  161. MAT3shear(MAT3mat result_mat, double xshear, double yshear)
  162. {
  163.    MAT3identity(result_mat);
  164.  
  165.    result_mat[2][0] = xshear;
  166.    result_mat[2][1] = yshear;
  167. }
  168.  
  169.